import { type AlovaMethodHandler, useRequest } from "alova/client";
import type { Reactive } from "vue";

// 分页接口响应类型
type PageResVO<T> = {
    code: number;
    msg: string;
    data?: {
        list: T[];
        total: number;
        current: number;
        size: number;
        pages: number;
        extend?: Record<string, any>;
    };
};

/**
 * 分页请求hook，基于alova的useRequest实现
 * @param {Function} methodHandler 请求方法，alova Method 实例
 * @param {Object} searchForm 搜索表单参数
 * @param {number} size 每页显示条数，默认 10 条
 * @returns {Object} 返回分页相关数据和方法
 *   @property {Array} list - 数据列表
 *   @property {number} page - 当前页码
 *   @property {number} pageSize - 每页数量
 *   @property {number} total - 总数据量
 *   @property {boolean} loading - 加载状态
 *   @property {number} pageCount - 总页数
 *   @property {number} isLastPage - 是否最后一页
 *   @property {Object} extend - 扩展数据字段
 *   @property {Function} send - 请求分页接口函数
 *   @property {Function} sendForLatestData - 发送请求并返回当前页最新数据（击穿缓存）
 *   @property {Function} handleReset - 清空查询表单参数发起请求并回到第一页
 *   @property {Function} handleSearch - 搜索函数，携带查询表单表单发起请求并回到第一页
 * @example
 * const searchForm = reactive( name: "", code: "" });
 * const { list, loading, page, pageSize, total, pageCount, isLastPage, extend, send, sendForLatestData, handleReset, handleSearch }
 *      = usePage(Apis.CategoryAdmin.page, searchForm, 10);
 */
export const usePaging = <RowDataType = any>(
    methodHandler: AlovaMethodHandler,
    searchForm: Reactive<Record<string, any>> = {},
    size = 10
) => {
    const defaultPageSize: number = size;

    const page = ref(1); // 当前页码
    const pageSize = ref(defaultPageSize); // 每页显示条数
    const total = ref(0); // 总条数

    const { data, loading, send } = useRequest(
        (searchForm = {}, current: number = 1, size: number = defaultPageSize) => {
            // 过滤空值请求参数
            Object.keys(searchForm).forEach(item => {
                if (searchForm[item] === null || searchForm[item] === undefined || searchForm[item] === "") {
                    Reflect.deleteProperty(searchForm, item);
                }
            });
            return methodHandler({ params: { size, current, ...searchForm } });
        },
        { initialData: { data: { list: [] } } }
    ).onSuccess(res => {
        page.value = res.data.data.current;
        pageSize.value = res.data.data.size;
        total.value = res.data.data.total;
    });

    // 总页数
    const pageCount = computed(() => Math.ceil(total.value / pageSize.value));
    // 是否最后一页
    const isLastPage = computed(() => page.value === pageCount.value);
    // 响应的列表数据
    const list = computed(() => (data.value as PageResVO<RowDataType>)?.data?.list ?? []);

    // 添加时间参数，击穿缓存，拉取当前页最新数据
    const sendForLatestData = () => send({ time: Date.now() }, page.value, pageSize.value);

    const handleReset = async () => {
        await send();
        Object.keys(searchForm).forEach(key => {
            searchForm[key] = void 0;
        });
    };

    const handleSearch = async (searchKeys: any = {}) => {
        Object.keys(searchKeys).forEach(key => {
            searchForm[key] = searchKeys[key];
        });
        await send(searchForm, 1);
        Object.keys(searchForm).forEach(key => {
            searchForm[key] = void 0;
        });
    };

    return {
        loading,
        list,
        page,
        pageSize,
        total,
        pageCount,
        isLastPage,
        extend: (data.value as PageResVO<RowDataType>)?.data?.extend ?? {},
        send,
        sendForLatestData,
        handleReset,
        handleSearch
    };
};
